import { Controller } from '@nestjs/common';
import { Tool } from '@rekog/mcp-nest';
import { z } from 'zod';
import { ToolResponse } from '../type';
import { default as axios, AxiosError } from 'axios';

@Controller('weather-api')
export class WeatherApiController {
  constructor() {}
  // API端点配置
  private readonly GEOCODING_URL = 'https://geocoding-api.open-meteo.com/v1/search';
  private readonly WEATHER_URL = 'https://api.open-meteo.com/v1/forecast';
  // 气象代码转换表
  private getWeatherCondition(code: number): string {
    const conditions: { [key: number]: string } = {
      0: '晴',
      1: '少云',
      2: '多云',
      3: '阴',
      45: '雾',
      51: '小雨',
      61: '中雨',
      80: '大雨',
      95: '雷暴'
    };
    return conditions[code] || '未知天气';
  }

  @Tool({
    name: 'weather-api',
    description: '通过Open-Meteo API获取实时天气数据',
    parameters: z
      .object({
        city: z.string().describe('目标城市英文名称')
      })
      .required()
  })
  async exec({ city }: { city: string }): Promise<ToolResponse> {
    if (!city) {
      return {
        isError: true,
        content: [
          {
            type: 'text',
            text: `请输入城市名称`
          }
        ]
      };
    }

    try {
      // 步骤1：获取城市坐标
      const geoResponse = await axios.get(this.GEOCODING_URL, {
        params: {
          name: city,
          count: 1,
          language: 'en',
          format: 'json'
        }
      });

      if (!geoResponse.data.results || !geoResponse.data.results?.length) {
        return {
          isError: true,
          content: [
            {
              type: 'text',
              text: `找不到名为${city}的城市`
            }
          ]
        };
      }

      const location = geoResponse.data.results[0];

      // 步骤2：获取天气数据
      const weatherResponse = await axios.get(this.WEATHER_URL, {
        params: {
          latitude: location.latitude,
          longitude: location.longitude,
          current: [
            'temperature_2m', // 2米高度气温
            'relative_humidity_2m', // 相对湿度
            'apparent_temperature', // 体感温度
            'precipitation', // 降水量
            'weather_code', // 气象代码
            'wind_speed_10m' // 10米风速
          ],
          daily: [
            'temperature_2m_max', // 最高温度
            'temperature_2m_min' // 最低温度
          ],
          timezone: 'auto'
        }
      });

      const current = weatherResponse.data.current;
      const daily = weatherResponse.data.daily;

      // 步骤3：转换气象代码
      const condition = this.getWeatherCondition(current.weather_code);

      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify({
              city: location.name,
              temperature: Math.round(current.temperature_2m),
              temperatureMax: Math.round(daily.temperature_2m_max[0]),
              temperatureMin: Math.round(daily.temperature_2m_min[0]),

              condition,
              humidity: current.relative_humidity_2m,
              windSpeed: current.wind_speed_10m,
              feelsLike: Math.round(current.apparent_temperature),
              precipitation: current.precipitation
            })
          }
        ]
      };
    } catch (error) {
      if (error instanceof AxiosError) {
        return {
          isError: true,
          content: [
            {
              type: 'text',
              text: `API请求失败：${error.message}`
            }
          ]
        };
      }

      return {
        isError: true,
        content: [
          {
            type: 'text',
            text: `未知错误：${error.message}`
          }
        ]
      };
    }
  }
}
